/**
 * Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
 *
 * @author Alexander Rose <alexander.rose@weirdbyte.de>
 * @author David Sehnal <david.sehnal@gmail.com>
 */

import { parseGRO } from '../gro/parser';

const groString = `MD of 2 waters, t= 4.2
    6
    1WATER  OW1    1   0.126   1.624   1.679  0.1227 -0.0580  0.0434
    1WATER  HW2    2   0.190   1.661   1.747  0.8085  0.3191 -0.7791
    1WATER  HW3    3   0.177   1.568   1.613 -0.9045 -2.6469  1.3180
    2WATER  OW1    4   1.275   0.053   0.622  0.2519  0.3140 -0.1734
    2WATER  HW2    5   1.337   0.002   0.680 -1.0641 -1.1349  0.0257
    2WATER  HW3    6   1.326   0.120   0.568  1.9427 -0.8216 -0.0244
   1.82060   2.82060   3.82060`;

const groStringHighPrecision = `Generated by trjconv : 2168 system t=  15.00000
    3
    1ETH     C1    1   2.735383   2.672010   1.450194  0.2345 -0.1622 0.2097
    1ETH    H11    2   0.015804   2.716597   1.460588  0.8528 -0.7984 0.6605
    1ETH    H12    3   2.744822   2.565544   1.409227 -2.3812  2.8618 1.8101
   1.82060   2.82060   3.82060`;

describe('gro reader', () => {
    it('basic', async () => {
        const parsed = await parseGRO(groString).run();

        if (parsed.isError) {
            console.log(parsed);
            return;
        }
        const groFile = parsed.result;
        const data = groFile.structures[0];

        const { header, atoms } = data;
        expect(header.title).toBe('MD of 2 waters');
        expect(header.timeInPs).toBeCloseTo(4.2);
        expect(header.hasVelocities).toBe(true);
        expect(header.precision.position).toBe(3);
        expect(header.precision.velocity).toBe(4);
        expect(header.box[0]).toBeCloseTo(1.82060, 0.00001);
        expect(header.box[1]).toBeCloseTo(2.82060, 0.00001);
        expect(header.box[2]).toBeCloseTo(3.82060, 0.00001);

        expect(atoms.count).toBe(6);

        expect(atoms.x.value(0)).toBeCloseTo(0.126, 0.001);
        expect(atoms.y.value(0)).toBeCloseTo(1.624, 0.001);
        expect(atoms.z.value(0)).toBeCloseTo(1.679, 0.001);

        expect(atoms.vx.value(5)).toBeCloseTo(1.9427, 0.0001);
        expect(atoms.vy.value(5)).toBeCloseTo(-0.8216, 0.0001);
        expect(atoms.vz.value(5)).toBeCloseTo(-0.0244, 0.0001);
    });

    it('high precision', async () => {
        const parsed = await parseGRO(groStringHighPrecision).run();

        if (parsed.isError) {
            console.log(parsed);
            return;
        }

        const groFile = parsed.result;
        const data = groFile.structures[0];

        const { header, atoms } = data;
        expect(header.title).toBe('Generated by trjconv : 2168 system');
        expect(header.timeInPs).toBeCloseTo(15);
        expect(header.hasVelocities).toBe(true);
        expect(header.precision.position).toBe(6);
        expect(header.precision.velocity).toBe(4);
        expect(header.box[0]).toBeCloseTo(1.82060, 0.00001);
        expect(header.box[1]).toBeCloseTo(2.82060, 0.00001);
        expect(header.box[2]).toBeCloseTo(3.82060, 0.00001);

        expect(atoms.count).toBe(3);

        expect(atoms.x.value(1)).toBeCloseTo(0.015804, 0.000001);
        expect(atoms.y.value(1)).toBeCloseTo(2.716597, 0.000001);
        expect(atoms.z.value(1)).toBeCloseTo(1.460588, 0.000001);

        expect(atoms.vx.value(0)).toBeCloseTo(0.2345, 0.0001);
        expect(atoms.vy.value(0)).toBeCloseTo(-0.1622, 0.0001);
        expect(atoms.vz.value(0)).toBeCloseTo(0.2097, 0.0001);
    });
});
